package com.rw.coco.reply.impl.util;

import com.rw.coco.reply.constants.DiceReplyKey;
import com.rw.coco.reply.reader.CocoPropertiesReader;
import com.rw.coco.util.CocoStringUtil;
import com.rw.tool.util.expression.exception.ExpressionException;
import com.rw.tool.util.expression.exception.InfixExpressionParseException;
import com.rw.tool.util.expression.exception.ParenthesesNotMatchException;
import com.rw.tool.util.expression.exception.SignException;
import com.rw.tool.util.expression.state.InfixExpressionState;
import com.rw.tool.util.string.StringFormatter;

import java.text.MessageFormat;

/**
 * 表达式异常工具类
 */
public class ExpressionExceptionUtil {
    /**
     * 将表达式异常转化为报错的字符串
     */
    public static String exceptionToString(ExpressionException exception, CocoPropertiesReader reader) {
        if (exception instanceof SignException) {
            // 符号异常
            SignException signException = (SignException) exception;
            String sign = signException.getSign();
            return StringFormatter.format(reader.get(DiceReplyKey.SIGN_EXCEPTION_MSG), sign);
        } else if (exception instanceof ParenthesesNotMatchException) {
            // 括号未匹配异常
            return reader.get(DiceReplyKey.PARENTHESES_EXCEPTION);
        } else if (exception instanceof InfixExpressionParseException) {
            // 中缀表达式解析异常
            InfixExpressionParseException parseException = (InfixExpressionParseException) exception;
            return getParseExceptionMsg(parseException, reader);
        }
        throw exception;
    }

    private static String getParseExceptionMsg(InfixExpressionParseException parseException, CocoPropertiesReader reader) {
        int index = parseException.getIndex();
        String expression = parseException.getExpression();
        InfixExpressionState state = parseException.getState();

        String errorHint = CocoStringUtil.openWindow(expression, index, 3);
        String errorMessage = getErrorMessage(state, reader);

        String template = reader.get(DiceReplyKey.PARSE_EXCEPTION_MSG);
        return errorMessage + MessageFormat.format(template, index + 1, errorHint);
    }

    // 获得异常文本
    private static String getErrorMessage(InfixExpressionState state, CocoPropertiesReader reader) {
        switch (state) {
            case START:
                return reader.get(DiceReplyKey.EXPRESSION_START_EXCEPTION);
            case AFTER_CALCULATION:
                return reader.get(DiceReplyKey.AFTER_CALCULATION_EXCEPTION);
            case AFTER_NUMBER:
                return reader.get(DiceReplyKey.AFTER_NUMBER_EXCEPTION);
            case AFTER_LEFT_PARENTHESES:
                return reader.get(DiceReplyKey.AFTER_LEFT_PARENTHESES);
            case AFTER_RIGHT_PARENTHESES:
                return reader.get(DiceReplyKey.AFTER_RIGHT_PARENTHESES);
            default:
                return "Unknown InfixExpressionState:" + state;
        }
    }
}
